[iOS 10] NSMeasurementを使って簡単に単位を変換する
はじめに
こんにちは!モバイルアプリサービス部の加藤 潤です。
今回はiOS 10で追加された NSMeasurement
やその周辺クラス群について取り上げたいと思います。
これからご紹介するNSMeasurementなどはObjective-Cの世界ではclassですが、Swiftの世界ではstructureです。説明文ではクラスとして表現(頭にNSが付く)しますが、ソースコード部分はSwiftなので頭にNSは付きません。機能としては同じものを指しています。
iOS 10で追加されたクラス群
NSMeasurement
- 値を異なる単位に変換したり、2つの値の合計や差分を計算する機能を提供する。
NSMeasurementFormatter
を使うことでローカライズした値と単位をユーザーに表示することが可能。NSUnit
とdouble
値で構成される。
NSUnit
- 単位を表す。
NSUnit
自体は抽象クラスであり、実際にはサブクラスを使用する。NSUnit
のサブクラスはMeasurementFormatter
を使ったNSMeasurement
の文字列表現の生成に使用されるsymbol
を持つ。
NSDimension
- 次元を持つ単位を表す。
NSUnit
のサブクラス。NSDimension
自体は抽象クラスであり、実際にはサブクラスを使用する。- 同じ種類の異なる単位に変換する機能を提供する。
- Foundationフレームワークが一般的な物理量(質量、長さ、期間、速度など)を表す様々なサブクラスを提供してくれている。
- 次元を持つ単位を扱う場合はFoundationフレームワークのサブクラスを使用するか、もしくは
NSDimension
のサブクラスを自作する。 - 次元を持たない単位(count, score, ratioなど)を表す場合は
NSUnit
のサブクラスを自作する。
- 次元を持つ単位を扱う場合はFoundationフレームワークのサブクラスを使用するか、もしくは
Foundationフレームワークが提供するNSDimensionのサブクラス(一部)
- 以下はFoundationフレームワークが提供する
NSDimension
のサブクラスの一部です。 他にもたくさんありますので、詳細はAPI Referenceをご覧ください。NSUnitAngle
(角度)NSUnitDuration
(期間)NSUnitMass
(質量)NSUnitSpeed
(速度)
NSMeasurementFormatter
NSUnit
とNSMeasurement
を適切にフォーマット、ローカライズする機能を提供する。
NSMeasurementを使って単位を変換する
- 時間を秒に変換してみます。
// 「24時間」を定義 var hours = Measurement(value: 24, unit: UnitDuration.hours) print(hours) // 24.0 hr // 「24時間」を「秒」に変換(non-mutating) let seconds = hours.converted(to: UnitDuration.seconds) print(seconds) // 86400.0 s // 「24時間」を「秒」に変換(mutating) hours.convert(to: UnitDuration.seconds) print(hours) // 86400.0 s
NSMeasurementFormatterを使ってNSMeasurementをフォーマット、ローカライズする
NSMeasurementFormatter
を使ってNSMeasurement
をフォーマット、日本語にローカライズしてみます。
// 「24時間」を定義 var hours = Measurement(value: 24, unit: UnitDuration.hours) print(NSLocale.current) // en_US // ロケール設定なし(current localeが使われる) // unitStyle設定なし(NSFormattingUnitStyleMediumが使われる) let measurementFormatter = MeasurementFormatter() let string1 = measurementFormatter.string(from: hours) print(string1) // 24 hr // unitStyleをlongに設定 measurementFormatter.unitStyle = .long let string2 = measurementFormatter.string(from: hours) print(string2) // 24 hours // unitStyleをshortに設定 measurementFormatter.unitStyle = .short let string3 = measurementFormatter.string(from: hours) print(string3) // 24h // ロケール設定あり(ja_JP) measurementFormatter.locale = Locale(identifier: "ja_JP") let string4 = measurementFormatter.string(from: hours) print(string4) // 24時間
おわりに
NSMeasurement
とその関連クラス群の登場によって、単位の変換や計算が楽になりました。特に単位の変換ロジックを開発者が意識しなくて良くなったのは地味に嬉しいです。